package net.beaconcontroller.comp416project.view;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import net.beaconcontroller.comp416project.controller.Controller;
import net.beaconcontroller.comp416project.data.DataFlowMod;
import net.beaconcontroller.comp416project.model.HexIPString;
import net.beaconcontroller.comp416project.model.Model;

import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
/**
 * 
 * @author SHI ZHONGQI 10836265D from HK PolyU
 * @author JI ZHIHAO 13022865X from HK PolyU
 *
 */
public class View extends JFrame implements Observer{
	  static final int flowUpperLimit = 10;
	  private Model model;
	  private Controller controller;
	  private ArrayList<FlowChangeView> FCVList;
	  HashMap<String,OFFlowMod> flowMap;
	  JPanel container;
	  JPanel buttonContain;
	  JButton jbt_addFlow;
	  MutipleDiagram mutipleCharts;

	  public View (Model model) {
	       this.model = model;
	
	       this.model.addObserver(this);
	      
	       FCVList = new ArrayList<FlowChangeView>();
	       attachController(makeController());
	       buildUI();
	       //this.model.setVarMutipleDiagram(this.varmutipleCharts);
	       
	  }
	  
	  public void attachController(Controller controller) {
		    
		  this.controller = controller;
	
	  }
		
	  public Controller makeController() {
		     
		  return new Controller(this, model);
		
	  }
	  
	  private void buildUI() {
		  container = new JPanel(new GridLayout(0,15));
		  setLayout(new BorderLayout());
		  buttonContain = new JPanel();
		  jbt_addFlow = new JButton("New FLow");
		  jbt_addFlow.setActionCommand("View_addFlow");
		  jbt_addFlow.addActionListener(controller);
		  buttonContain.add(jbt_addFlow);
		  
		  add(container,BorderLayout.CENTER);
		  add(buttonContain,BorderLayout.SOUTH);
		  
	  }

	  public void openFCV(){
		  	FlowChangeView fcv = new FlowChangeView(controller);
			fcv.pack();
			fcv.setVisible(true);
			FCVList.add(fcv);  
	  }
	  
	  public void openFCV(OFFlowMod fm,String name){
		FlowChangeView fcv = new FlowChangeView(fm,controller,name);
		fcv.pack();
		fcv.setVisible(true);
		FCVList.add(fcv);  
	  }
	  
	  public ArrayList<FlowChangeView> getFCVList(){
		  return FCVList;
	  }
	  
	  public FlowChangeView getFCV(){
		  boolean find=false;
		  int i;
		  for(i=0;i<FCVList.size();i++){
			  if(FCVList.get(i).isFocused())
			  { 
				  find =true;
				  break;
			  }
			  
			 
		  }
		  if(find)
			  return FCVList.get(i);
		  else
			  return null;
	  }
	  
	  public void update(HashMap<String,OFFlowMod> flowMap){
		  container.removeAll();
		  //System.out.println("here the size is "+flowMap.size());
		  ArrayList<String> flowList = new ArrayList<String>(flowMap.keySet());
		  container.add(new JLabel("Flow"));
		  container.add(new JLabel("InPort"));
		  container.add(new JLabel("DL_DST"));
		  container.add(new JLabel("DL_SRC"));
		  container.add(new JLabel("DL_TYPE"));
		  container.add(new JLabel("NW_DST"));
		  container.add(new JLabel("NW_SRC"));
		  container.add(new JLabel("NW_PROTO"));
		  container.add(new JLabel("NW_TOS"));
		  container.add(new JLabel("TP_DST"));
		  container.add(new JLabel("TP_SRC"));
		  container.add(new JLabel("IdelTime"));
		  container.add(new JLabel("HardTimeOut"));
		  container.add(new JLabel("Priority"));
		  container.add(new JLabel("Botton"));
		  for(int i=0;i<flowList.size();i++){
			 
			 String name = flowList.get(i);
			 OFFlowMod fm = flowMap.get(name);
			 OFMatch match = fm.getMatch();
		
			 JButton jbt_modify= new JButton("Modify");
			 jbt_modify.setActionCommand(name);
			 jbt_modify.addActionListener(controller);
			 container.add(new JLabel(name));
			 container.add(new JLabel(""+match.getInputPort()));
			 container.add(new JLabel(HexIPString.toHexString(match.getDataLayerDestination())));
			 container.add(new JLabel(HexIPString.toHexString(match.getDataLayerSource())));
			 container.add(new JLabel(""+match.getDataLayerType()));
			 container.add(new JLabel(HexIPString.toIp(match.getNetworkDestination(),match.getNetworkDestinationMaskLen())));
			 container.add(new JLabel(HexIPString.toIp(match.getNetworkSource(),match.getNetworkSourceMaskLen())));
			 container.add(new JLabel(""+match.getNetworkProtocol()));
			 container.add(new JLabel(""+match.getNetworkTypeOfService()));
			 container.add(new JLabel(""+match.getTransportDestination()));
			 container.add(new JLabel(""+match.getTransportSource()));
			 container.add(new JLabel(""+fm.getIdleTimeout()));
			 container.add(new JLabel(""+fm.getHardTimeout()));
			 container.add(new JLabel(""+fm.getPriority()));
			 container.add(jbt_modify);
			 
		 }
		  container.repaint();
		  this.repaint();
		  this.pack();
		 
	  }
	  
		
		public void mutipleUpdate(double data, int id,String result){
			mutipleCharts.setData(data,id-1);
			mutipleCharts.update(result,id-1);
		}
		
		boolean started=false;
		
		public void updateMutiple(){

			if(!started){
				mutipleCharts=new MutipleDiagram(flowUpperLimit);
				mutipleCharts.pack();
				mutipleCharts.setVisible(true);
				mutipleCharts.startThread();
				started = true;
			}
			
		}  
	  
	  
	  
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		
	}
}
